use rbatis::rbdc::DateTime;

use crate::model::vo::login_vo::TokenVo;
use crate::{
    db_pool, error::Result, model::system_admin::SystemAdmin, plugin::jwt::JWTClaims,
    utils::password_utils::PasswordUtils, APPLICATION_CONTEXT,
};

pub struct SystemAdminAuthService {}

impl SystemAdminAuthService {
    pub async fn login(&self, account: &str, raw_password: &str, code: &str) -> Result<TokenVo> {
        let code = code.to_lowercase();
        let raw_code = &APPLICATION_CONTEXT
            .cache_service
            .inner
            .get_str(&code)
            .await?;
        if !raw_code.eq(&code) {
            return Err("验证码错误！".into());
        }
        let sysadmin = SystemAdmin::select_account_one_by_name(db_pool!(), account)
            .await?
            .into_iter()
            .next()
            .unwrap();
        let password = sysadmin.password.unwrap_or_default();
        let salt = sysadmin.salt.unwrap_or_default();
        let result = PasswordUtils::verify(&password, raw_password, &salt);
        if result {
            // 销毁验证码
            let _ = &APPLICATION_CONTEXT
                .cache_service
                .inner
                .del_str(&code)
                .await?;
            let jwt = JWTClaims {
                id: sysadmin.id.unwrap_or_default().to_string().into(),
                account: sysadmin.account.unwrap_or_default().to_string().into(),
                permissions: vec![String::from("1")],
                role_ids: vec![String::from("1")],
                exp: DateTime::now().unix_timestamp() as usize + APPLICATION_CONTEXT.config.jwt_exp,
            };
            let token = jwt
                .generate_token(&APPLICATION_CONTEXT.config.jwt_secret)
                .unwrap_or_default();
            let vo = TokenVo {
                token: token.into(),
            };
            Ok(vo)
        } else {
            Err("账号或密码错误！".into())
        }
    }
}
